package br.com.usjt.sge.arduino;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

public class SerialTest implements SerialPortEventListener {

	SerialPort serialPort;
	/** A porta que usaremos */
	private static final String PORT_NAMES[] = { "/dev/ttyACM0", // Linux
			"COM5", // Windows
	};
	/** Fluxo de entrada bufferizado vindo da porta */
	private InputStream input;
	/** Fluxo de sa�da para a porta */
	private OutputStream output;
	/** Milissegundos para bloquear enquanto aguarda a abertura da porta */
	private static final int TIME_OUT = 2000;
	/** Bits por segundo padr�o para a porta COM comunicao com a porta serial */
	private static final int DATA_RATE = 9600;

	public void initialize() {
		CommPortIdentifier portId = null;
		Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

		// Faz itera��es procurando pela porta
		while (portEnum.hasMoreElements()) {
			CommPortIdentifier currPortId = (CommPortIdentifier) portEnum
					.nextElement();
			for (String portName : PORT_NAMES) {
				if (currPortId.getName().equals(portName)) {
					portId = currPortId;
					break;
				}
			}
		}

		if (portId == null) {
			System.out.println("Porta nao encontrada!");
			return;
		}

		try {
			// abre a porta serial, e usa o nome da classe para a appName
			serialPort = (SerialPort) portId.open(this.getClass().getName(),
					TIME_OUT);

			// define par�metros da porta
			serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8,
					SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

			// abre os fluxos
			input = serialPort.getInputStream();
			output = serialPort.getOutputStream();

			// adiciona os ouvintes de eventos
			serialPort.addEventListener(this);
			serialPort.notifyOnDataAvailable(true);
		} catch (Exception e) {
			System.err.println(e.toString());
		}
	}

	/**
	 * Isso dever� ser chamado quando voc� parar de usar a porta Isso ir�
	 * prevenir o travamento da porta em plataformas como Linux.
	 */
	public synchronized void close() {
		if (serialPort != null) {
			serialPort.removeEventListener();
			serialPort.close();
		}
	}

	/**
	 * Trata um evento na porta serial. L� os dados e os imprime.
	 */
	public synchronized void serialEvent(SerialPortEvent oEvent) {

		ArquivoXML arquivo = new ArquivoXML();

		if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
			try {
				int available = input.available();
				byte chunk[] = new byte[available];
				input.read(chunk, 0, available);
				
				String value = new String(chunk);
				
				//System.out.println(value);
				arquivo.arquivaXML(value);

				// Os resultados mostrados s�o dependentes do codepage
				// System.out.print(new String(chunk));
			} catch (Exception e) {
				System.err.println(e.toString());
			}
		}
		// Ignore todos os outros eventTypes, mas voc� deve considerar o resto.
	}

	public static void inicializaSerial() {

		SerialTest main = new SerialTest();
		main.initialize();
		System.out.println("Started");
	}
}
